#include <QtCore/QtCore>
#include <QtWidgets/QtWidgets>
#include "MapExtractorDialog.h"
#include "ui_MapExtractorDialog.h"
#include "MapExtractor.h"
#include "QLogger.h"


#define DEFAULT_INPUT_DIR			"input_dir"
#define DEFAULT_OUTPUT_DIR          "output_dir"
#define DEFAULT_IMAGE_DIR           "image_dir"

#define APP_ORGINAZATION            "Roc Studio"
#define APP_NAME                    "Netease Map Extractor"

MapExtractorDialog::MapExtractorDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::MapExtractorDialog)
    , mExtractor(0)
{
    ui->setupUi(this);

    QString appDir = QApplication::applicationDirPath();
    QSettings settings(APP_ORGINAZATION, APP_NAME);
    QString inputPath = settings.value(DEFAULT_INPUT_DIR, appDir).toString() + "/";
    ui->mEdtInputPath->setText(inputPath);

    QString outputPath = settings.value(DEFAULT_OUTPUT_DIR, appDir).toString() + "/";
    ui->mEdtOutputPath->setText(outputPath);

    QString imagePath = settings.value(DEFAULT_IMAGE_DIR, appDir).toString() + "/";
    ui->mEdtImgPath->setText(imagePath);

    ui->mEdtDetail->ensureCursorVisible();

    mExtractor = new MapExtractor();

    connect(mExtractor, SIGNAL(started(int)), SLOT(onExtractStarted(int)), Qt::QueuedConnection);
    connect(mExtractor, SIGNAL(progress(int)), SLOT(onExtractProgress(int)), Qt::QueuedConnection);
    connect(mExtractor, SIGNAL(detail(QString)), SLOT(onExtractDetail(QString)), Qt::QueuedConnection);
    connect(mExtractor, SIGNAL(completed(bool,int,QString)), SLOT(onExtractCompleted(bool,int,QString)), Qt::QueuedConnection);
}

MapExtractorDialog::~MapExtractorDialog()
{
    delete ui;

    delete mExtractor;
}

void MapExtractorDialog::onClickedBtnBrwInputPath()
{
    QString appDir = QApplication::applicationDirPath();

    QSettings settings(APP_ORGINAZATION, APP_NAME);
    QString defaultDir = settings.value(DEFAULT_INPUT_DIR, appDir).toString();

    QString dir = QFileDialog::getExistingDirectory(this, tr("Choose map path"), defaultDir);

    if (!dir.isEmpty())
    {
        // change the default directory and store it
        settings.setValue(DEFAULT_INPUT_DIR, dir);
        QString path = QDir::fromNativeSeparators(dir) + "/";
        ui->mEdtInputPath->setText(path);
    }
}

void MapExtractorDialog::onClickedBtnBrwOutputPath()
{
    QString appDir = QApplication::applicationDirPath();

    QSettings settings(APP_ORGINAZATION, APP_NAME);
    QString defaultDir = settings.value(DEFAULT_OUTPUT_DIR, appDir).toString();

    QString dir = QFileDialog::getExistingDirectory(this, tr("Choose path for output"), defaultDir);

    if (!dir.isEmpty())
    {
        // change the default directory and store it
        settings.setValue(DEFAULT_OUTPUT_DIR, dir);
        QString path = QDir::fromNativeSeparators(dir) + "/";
        ui->mEdtOutputPath->setText(path);
    }
}

void MapExtractorDialog::onClickedBtnBrwImagePath()
{
    QString appDir = QApplication::applicationDirPath();

    QSettings settings(APP_ORGINAZATION, APP_NAME);
    QString defaultDir = settings.value(DEFAULT_IMAGE_DIR, appDir).toString();

    QString dir = QFileDialog::getExistingDirectory(this, tr("Choose path for XY2 image"), defaultDir);

    if (!dir.isEmpty())
    {
        // change the default directory and store it
        settings.setValue(DEFAULT_IMAGE_DIR, dir);
        QString path = QDir::fromNativeSeparators(dir) + "/";
        ui->mEdtImgPath->setText(path);
    }
}

void MapExtractorDialog::onExtractStarted(int total)
{
    mTotal = total;

    ui->mProgressBar->setRange(0, total);
    ui->mProgressBar->setValue(0);
}

void MapExtractorDialog::onExtractProgress(int progress)
{
    ui->mProgressBar->setValue(progress);
}

void MapExtractorDialog::onExtractDetail(const QString &text)
{
    Q_LOG(Q_LOG_LVL_DEBUG, text);

    QDateTime dateTime = QDateTime::currentDateTime();
    QString date = dateTime.toString("hh:mm:ss.zzz");
    QString fmt = QString("%1 : %2\n").arg(date).arg(text);

    setTextColor(Qt::black);

    ui->mEdtDetail->insertPlainText(fmt);

    QTextCursor c = ui->mEdtDetail->textCursor();
    c.movePosition(QTextCursor::End);
    ui->mEdtDetail->setTextCursor(c);
}

void MapExtractorDialog::onExtractCompleted(bool finished, int errorCode, const QString &errorDesc)
{
    Q_LOG(Q_LOG_LVL_DEBUG, errorDesc);

    if (finished)
    {
        setTextColor(Qt::black);
    }
    else
    {
        setTextColor(Qt::red);
    }

    ui->mEdtDetail->insertPlainText(errorDesc);
    QTextCursor c = ui->mEdtDetail->textCursor();
    c.movePosition(QTextCursor::End);
    ui->mEdtDetail->setTextCursor(c);

    switchUIState(false);
}

void MapExtractorDialog::accept()
{
    if (mExtractor != 0)
    {
        QString inputPath = ui->mEdtInputPath->text();
        QString outputPath = ui->mEdtOutputPath->text();
        QString imagePath = ui->mEdtImgPath->text();
        bool result = mExtractor->run(inputPath, outputPath, imagePath);

        if (result)
        {
            switchUIState(true);
        }
    }
}

void MapExtractorDialog::reject()
{
    QDialog::reject();
}

void MapExtractorDialog::closeEvent(QCloseEvent *event)
{
    QDialog::closeEvent(event);
}

void MapExtractorDialog::switchUIState(bool extracting)
{
    ui->mEdtInputPath->setEnabled(!extracting);
    ui->mEdtOutputPath->setEnabled(!extracting);
    ui->mEdtImgPath->setEnabled(!extracting);
    ui->mBtnBrwInputPath->setEnabled(!extracting);
    ui->mBtnBrwOutputPath->setEnabled(!extracting);
    ui->mBtnBrwImgPath->setEnabled(!extracting);

    QPushButton *btn = ui->mButtonBox->button(QDialogButtonBox::Ok);
    btn->setEnabled(!extracting);
}

void MapExtractorDialog::setTextColor(const QColor &color)
{
    QTextCharFormat fmt;
    fmt.setForeground(color);
    QTextCursor cursor = ui->mEdtDetail->textCursor();
    cursor.mergeCharFormat(fmt);
    ui->mEdtDetail->mergeCurrentCharFormat(fmt);
}
